﻿using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BaseNet.Application.System.Dict.Dto;
using BaseNet.Core.Consts;
using BaseNet.Core.Dtos;
using BaseNet.Core.Utils;
using BaseNet.Entity.System;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Furion.DynamicApiController;
using System.Threading;

namespace BaseNet.Application.System.Dict
{
    /// <summary>
    /// 数据字典接口实现
    /// </summary>
    [ApiDescriptionSettings(Module = ModuleConsts.System)]
    [SecurityDefine(SecurityConsts.System_Dict)]
    public class DictService: IDynamicApiController
    {
        private readonly SqlSugarClient _db;
        public DictService(ISqlSugarRepository sqlSugarRepository)
        {
            _db = sqlSugarRepository.Context;
        }

        /// <summary>
        /// 添加数据字典字段
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task AddField(DictFieldSaveInput input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/addfield/"))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    if (await _db.Queryable<SysDictFieldEntity>().AnyAsync(o => o.FieldCode == input.FieldCode))
                        throw Oops.Oh("字典编码不可重复");
                    var entity = input.Adapt<SysDictFieldEntity>();
                    await _db.ExtInsertableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 修改数据字典字段
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditField(DictFieldSaveInput input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/editfield/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    if (await _db.Queryable<SysDictFieldEntity>().Where(o => o.Id != input.Id).AnyAsync(o => o.FieldCode == input.FieldCode))
                        throw Oops.Oh("字典编码不可重复");
                    var entity = await _db.Queryable<SysDictFieldEntity>()
                        .Where(o => o.Id == input.Id)
                        .FirstAsync();

                    InputSetEntityHelper.InputSetEntity(input, ref entity);

                    await _db.ExtUpdateableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 设置数据字典字段有效性
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SetFieldActive(PrivateEntityBase input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/setfieldactive/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    var entity = await _db.Queryable<SysDictFieldEntity>()
                        .Where(o => o.Id == input.Id)
                        .FirstAsync();
                    if (entity == null)
                        throw Oops.Oh("当前数据字典不存在");

                    entity.IsActive = !entity.IsActive;

                    await _db.ExtUpdateableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 删除数据字典字段
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task DelField(PrivateEntityBase input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/delfield/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    var entity = await _db.Queryable<SysDictFieldEntity>()
                        .Where(o => o.Id == input.Id)
                        .FirstAsync();
                    if (entity == null)
                        throw Oops.Oh("当前数据字典不存在");

                    await _db.ExtDeleteableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 获取数据字典字段详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<DictFieldDto> GetFieldInfo(PrivateEntityBase input)
        {
            var dto = await _db.Queryable<SysDictFieldEntity>()
                .Select<DictFieldDto>()
                .FirstAsync(o => o.Id == input.Id);
            if (dto == null)
                throw Oops.Oh("当前数据字典不存在");

            return dto;
        }

        /// <summary>
        /// 获取数据字典字段分页列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<SqlSugarPagedList<DictFieldDto>> GetFieldPagedList(PagedInput input)
        {
            var list = await _db.Queryable<SysDictFieldEntity>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.KeyWord), o => o.FieldCode.Contains(input.KeyWord) || o.FieldName.Contains(input.KeyWord) || o.Explain.Contains(input.KeyWord))
                .OrderBy(o => o.FieldCode)
                .Select<DictFieldDto>()
                .ToPagedListAsync(input.PageIndex, input.PageSize);

            return list;
        }



        /// <summary>
        /// 添加数据字典项
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task AddItem(DictItemSaveInput input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/additem/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    if (await _db.Queryable<SysDictItemEntity>().Where(o => o.DictFieldId == input.DictFieldId).AnyAsync(o => o.DictValue == input.DictValue))
                        throw Oops.Oh("数据字典值不可重复");

                    var entity = input.Adapt<SysDictItemEntity>();

                    await _db.ExtInsertableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 修改数据字典项
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditItem(DictItemSaveInput input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/edititem/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    if (await _db.Queryable<SysDictItemEntity>().Where(o => o.DictFieldId == input.DictFieldId).Where(o => o.Id != input.Id).AnyAsync(o => o.DictValue == input.DictValue))
                        throw Oops.Oh("数据字典值不可重复");

                    var entity = await _db.Queryable<SysDictItemEntity>()
                        .Where(o => o.Id == input.Id)
                        .FirstAsync();
                    if (entity == null)
                        throw Oops.Oh("当前数据字典项不存在");

                    InputSetEntityHelper.InputSetEntity(input, ref entity);

                    await _db.ExtUpdateableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 设置数据字典项有效性
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SetItemActive(PrivateEntityBase input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/setitemactive/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    var entity = await _db.Queryable<SysDictItemEntity>()
                        .Where(o => o.Id == input.Id)
                        .FirstAsync();
                    if (entity == null)
                        throw Oops.Oh("当前数据字典项不存在");

                    entity.IsActive = !entity.IsActive;

                    await _db.ExtUpdateableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 删除数据字典项
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task DelItem(PrivateEntityBase input)
        {
            using (var mutex = new Mutex(true, "/api/system/dict/delitem/" + input.Id))
            {
                try
                {
                    if (!mutex.WaitOne(0, true))//若存在接口堵塞，则直接退出
                        throw Oops.Oh("当前接口存在正在进行的访问");

                    var entity = await _db.Queryable<SysDictItemEntity>()
                        .Where(o => o.Id == input.Id)
                        .FirstAsync();
                    if (entity == null)
                        throw Oops.Oh("当前数据字典项不存在");

                    await _db.ExtDeleteableAsync(entity);
                }
                finally
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch (Exception) { }
                    mutex.Close();
                    mutex.Dispose();
                }
            }
        }

        /// <summary>
        /// 获取数据字典项详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<DictItemDto> GetItemInfo(PrivateEntityBase input)
        {
            var dto = await _db.Queryable<SysDictItemEntity>()
                .Select<DictItemDto>()
                .FirstAsync(o => o.Id == input.Id);
            if (dto == null)
                throw Oops.Oh("当前数据字典项不存在");

            return dto;
        }

        /// <summary>
        /// 获取指定字典所有列表项
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<DictItemDto>> GetList(PrivateEntityBase input)
        {
            var list = await _db.Queryable<SysDictItemEntity>()
                .Where(o => o.DictFieldId == input.Id)
                .OrderBy(o => o.Sort)
                .Select<DictItemDto>()
                .ToListAsync();

            return list;
        }



        /// <summary>
        /// 获取数据字典枚举列表
        /// 用于下拉框
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AllowAnonymous]
        public async Task<List<SelectItemDto>> GetEnumList(PrivateEntityBase input)
        {
            var dictFieldEntity = await _db.Queryable<SysDictFieldEntity>()
                .FirstAsync(o => o.FieldCode == input.Id);
            if (dictFieldEntity == null)
                throw Oops.Oh("当前数据字典不存在");
            var list = await _db.Queryable<SysDictItemEntity>()
                .Where(o => o.DictFieldId == dictFieldEntity.Id)
                .Where(o => o.IsActive == true)
                .OrderBy(o => o.Sort)
                .Select(o => new SelectItemDto
                {
                    Value = o.DictValue,
                    Text = o.DictValue
                }).ToListAsync();

            return list;
        }
    }
}
